﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace MineSweeperChallenge.Sweepers
{
    class SimpleSweeper : ISweeper
    {
        private CompleteRandomSweeper mCompleteRandomSweeper = new CompleteRandomSweeper();

        public string Name
        {
            get { return "Simple sweeper"; }
        }

        public string Version
        {
            get { return "v1.0"; }
        }

        public string Creator
        {
            get { return "Robin Hermanussen"; }
        }

        public int[] Sweep(int[][] pMinefield, int pTotalMines)
        {
            if (pMinefield.SelectMany(pArray => pArray).Count(pValue => pValue != -2) == 0)
            {
                // no fields have been cleared yet; take a field in the center
                return new int[] { pMinefield.Length / 2, pMinefield[0].Length / 2 };
            }
            // loop through mine indicators, from low risk to high risk
            for (int lMineIndicator = 0; lMineIndicator <= 3; lMineIndicator++)
            {
                for (int lX = 0; lX < pMinefield.Length; lX++)
                {
                    if (pMinefield[lX].Count(pValue => pValue == lMineIndicator) > 0)
                    {
                        // loop through the elements in this line
                        for (int lY = 0; lY < pMinefield[lX].Length; lY++)
                        {
                            if (pMinefield[lX][lY] == lMineIndicator)
                            {
                                int[] lUncheckedAdjacentField = GetUncheckedAdjacentField(pMinefield, lX, lY);
                                if (lUncheckedAdjacentField != null) return lUncheckedAdjacentField;
                            }
                        }
                    }
                }
            }
            // fallback to random if no strategy works
            return mCompleteRandomSweeper.Sweep(pMinefield, pTotalMines);
        }

        private static int[] GetUncheckedAdjacentField(int[][] pMinefield, int pX, int pY)
        {
            bool lIsBoundLeft = pX <= 0;
            bool lIsBoundRight = pX >= pMinefield.Length - 1;
            bool lIsBoundTop = pY <= 0;
            bool lIsBoundBottom = pY >= pMinefield[0].Length - 1;
            if (!lIsBoundLeft && !lIsBoundTop && pMinefield[pX - 1][pY - 1] == -2) return new int[] {pX - 1, pY - 1};
            if (!lIsBoundTop && pMinefield[pX][pY - 1] == -2) return new int[] { pX, pY - 1 };
            if (!lIsBoundRight && !lIsBoundTop && pMinefield[pX + 1][pY - 1] == -2) return new int[] { pX + 1, pY - 1 };
            if (!lIsBoundRight && pMinefield[pX + 1][pY] == -2) return new int[] { pX + 1, pY };
            if (!lIsBoundRight && !lIsBoundBottom && pMinefield[pX + 1][pY + 1] == -2) return new int[] { pX + 1, pY + 1 };
            if (!lIsBoundBottom && pMinefield[pX][pY + 1] == -2) return new int[] { pX, pY + 1 };
            if (!lIsBoundLeft && !lIsBoundBottom && pMinefield[pX - 1][pY + 1] == -2) return new int[] { pX - 1, pY + 1 };
            if (!lIsBoundLeft && pMinefield[pX - 1][pY] == -2) return new int[] { pX - 1, pY };
            return null;
        }
    }
}
